package com.diandian.backend.log.service;

import com.diandian.backend.log.constants.TaskStatusEnum;
import com.diandian.base.boot.starter.exception.DefaultException;
import com.diandian.base.boot.starter.response.PageResult;
import com.diandian.backend.log.domain.LogTask;
import com.diandian.backend.log.dto.*;
import com.diandian.backend.log.mapper.LogTaskMapper;
import com.diandian.backend.log.resp.LogTaskDetailResp;
import com.diandian.backend.log.resp.LogTaskPageResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.diandian.backend.log.resp.LogTaskListResp;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class LogTaskService {

    @Autowired
    private LogTaskMapper logTaskMapper;

    @Autowired
    private LogTaskProcessService logTaskProcessService;

    public PageResult page(LogTaskPageParamDTO requestDTO){

        requestDTO.check();
        int pageNum = requestDTO.getPageNum();
        int pageSize = requestDTO.getPageSize();

        // 查询总数
        int totalCount = logTaskMapper.getCount(requestDTO);

        // 查询数据集合
        List<LogTask> dataList = logTaskMapper.getPage(requestDTO, requestDTO.getPageSize(), (requestDTO.getPageNum() - 1) * requestDTO.getPageSize());

        // 组装数据
        List<LogTaskPageResp> respList = new ArrayList<>();
        if(dataList != null && dataList.size() > 0){
            dataList.stream().forEach( x ->{
                LogTaskPageResp item = new LogTaskPageResp();
                item.setId(x.getId());
                item.setBelong(x.getBelong());
                item.setBusinessType(x.getBusinessType());
                item.setBusinessId(x.getBusinessId());
                item.setTaskId(x.getTaskId());
                item.setTaskName(x.getTaskName());
                item.setPercent(x.getPercent());
                item.setStatus(x.getStatus());
                item.setExpectedEndTime(x.getExpectedEndTime());
                item.setRemark(x.getRemark());
                item.setCreateUserId(x.getCreateUserId());
                item.setCreateUserName(x.getCreateUserName());
                item.setCreateTime(x.getCreateTime());
                item.setUpdateTime(x.getUpdateTime());
                item.setStatusName(statusNameHandler(x.getStatus(), x.getExpectedEndTime()));
//                item.setDel(x.getDel());
             respList.add(item);
            });
        }

        return new PageResult(pageNum, pageSize, totalCount, respList);
    }

    private String statusNameHandler(String status, Date expectedEndTime){

        if(status == null || "".equals(status)){
            return TaskStatusEnum.UNKNOWN.getName();
        }

        // 完成
        if(status.equals(TaskStatusEnum.FINISH.getType())){
            return TaskStatusEnum.FINISH.getName();
        }

        // 取消
        if(status.equals(TaskStatusEnum.CANCEL.getType())){
            return TaskStatusEnum.CANCEL.getName();
        }

        // 暂停
        if(status.equals(TaskStatusEnum.PAUSE.getType())){
            return TaskStatusEnum.PAUSE.getName();
        }

        // 待执行
        if(status.equals(TaskStatusEnum.READY.getType())){
            return TaskStatusEnum.READY.getName();
        }

        if(status.equals(TaskStatusEnum.RUNNING.getType())){
            // 超时
            if(expectedEndTime != null && new Date().after(expectedEndTime)){
                return TaskStatusEnum.OUTTIME.getName();
            // 进行中
            } else {
                return TaskStatusEnum.RUNNING.getName();
            }
        }

        return TaskStatusEnum.UNKNOWN.getName();
    }

    public List<LogTaskListResp> getList(LogTaskListParamDTO requestDTO){

        // 查询数据集合
        List<LogTask> dataList = logTaskMapper.getList(requestDTO);

        // 组装数据
        List<LogTaskListResp> respList = new ArrayList<>();
        if(dataList != null && dataList.size() > 0){
            dataList.stream().forEach( x ->{
                LogTaskListResp item = new LogTaskListResp();
                item.setId(x.getId());
                item.setBelong(x.getBelong());
                item.setBusinessType(x.getBusinessType());
                item.setBusinessId(x.getBusinessId());
                item.setTaskId(x.getTaskId());
                item.setTaskName(x.getTaskName());
                item.setPercent(x.getPercent());
                item.setStatus(x.getStatus());
                item.setExpectedEndTime(x.getExpectedEndTime());
                item.setRemark(x.getRemark());
                item.setCreateUserId(x.getCreateUserId());
                item.setCreateUserName(x.getCreateUserName());
                item.setCreateTime(x.getCreateTime());
                item.setUpdateTime(x.getUpdateTime());
                item.setDel(x.getDel());
                respList.add(item);
            });
        }

        return respList;
    }

    public LogTaskDetailResp getDetail(LogTaskDetailParamDTO param) {

        param.check();

        // 查询参数优先级逻辑
        LogTaskDetailParamDTO queryDTO = new LogTaskDetailParamDTO();
        if(param.getId() != null){
            queryDTO.setId(param.getId());
        } else if(param.getTaskId() != null && !"".equals(param.getTaskId())) {
            queryDTO.setTaskId(param.getTaskId());
        } else {
            queryDTO.setBusinessId(param.getBusinessId());
            queryDTO.setBusinessType(param.getBusinessType());
        }

        LogTask dbData = logTaskMapper.getDetail(queryDTO);
        if(dbData == null){
            return null;
        }

        LogTaskDetailResp result = new LogTaskDetailResp();
        result.setId(dbData.getId());
        result.setBelong(dbData.getBelong());
        result.setBusinessType(dbData.getBusinessType());
        result.setBusinessId(dbData.getBusinessId());
        result.setTaskId(dbData.getTaskId());
        result.setTaskName(dbData.getTaskName());
        result.setPercent(dbData.getPercent());
        result.setStatus(dbData.getStatus());
        result.setExpectedEndTime(dbData.getExpectedEndTime());
        result.setRemark(dbData.getRemark());
        result.setCreateUserId(dbData.getCreateUserId());
        result.setCreateUserName(dbData.getCreateUserName());
        result.setCreateTime(dbData.getCreateTime());
        result.setUpdateTime(dbData.getUpdateTime());
        result.setStatusName(statusNameHandler(dbData.getStatus(), dbData.getExpectedEndTime()));
//        result.setDel(dbData.getDel());
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateReady(LogTaskUpdateByIdParamDTO param) {

        param.check();

        // 查询参数优先级逻辑
        LogTaskDetailParamDTO queryDTO = new LogTaskDetailParamDTO();
        if(param.getId() != null){
            queryDTO.setId(param.getId());
        } else if(param.getTaskId() != null && !"".equals(param.getTaskId())) {
            queryDTO.setTaskId(param.getTaskId());
        } else {
            queryDTO.setBusinessId(param.getBusinessId());
            queryDTO.setBusinessType(param.getBusinessType());
        }

        // 执行查询
        LogTask dbData = logTaskMapper.getDetail(queryDTO);
        if(dbData == null){
            throw new DefaultException("更新的记录不存在");
        }
        if(!dbData.getStatus().equals(TaskStatusEnum.READY.getType())){
            throw new DefaultException("仅待执行的任务允许修改");
        }

        param.setId(dbData.getId());
        param.setUpdateTime(dbData.getUpdateTime() == null ? new Date() : dbData.getUpdateTime());
        logTaskMapper.updateReady(param);

        // 保存进程日志
        LogTaskProcessAddParamDTO processAddParamDTO = new LogTaskProcessAddParamDTO();
        processAddParamDTO.setBelong(param.getBelong());
        processAddParamDTO.setBusinessId(dbData.getBusinessId());
        processAddParamDTO.setBusinessType(dbData.getBusinessType());
        processAddParamDTO.setTaskId(dbData.getTaskId());
        processAddParamDTO.setContent("修改了任务基本信息");
        processAddParamDTO.setOperaterUserId(param.getCreateUserId());
        processAddParamDTO.setOperatorUserName(param.getCreateUserName());
        logTaskProcessService.add(processAddParamDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(LogTaskUpdateStatusParamDTO param) {

        param.check();

        // 查询参数优先级逻辑
        LogTaskDetailParamDTO queryDTO = new LogTaskDetailParamDTO();
        if(param.getId() != null){
            queryDTO.setId(param.getId());
        } else if(param.getTaskId() != null && !"".equals(param.getTaskId())) {
            queryDTO.setTaskId(param.getTaskId());
        } else {
            queryDTO.setBusinessId(param.getBusinessId());
            queryDTO.setBusinessType(param.getBusinessType());
        }

        // 执行查询
        LogTask dbData = logTaskMapper.getDetail(queryDTO);
        if(dbData == null){
            throw new DefaultException("更新的记录不存在");
        }

        if(param.getStatus().equals(dbData.getStatus())){
            throw new DefaultException("已执行过此操作");
        }

        if(!TaskStatusEnum.READY.contains(param.getStatus())){
            throw new DefaultException("不支持此操作");
        }

        if(param.getStatus().equals(TaskStatusEnum.READY.getType())){
            throw new DefaultException("不支持此操作");
        }

        // 开始任务：仅待执行和暂停的任务可以执行此操作
        String dbStatus = dbData.getStatus();
        if(param.getStatus().equals(TaskStatusEnum.RUNNING.getType()) && !TaskStatusEnum.READY.getType().equals(dbStatus)
                && !TaskStatusEnum.PAUSE.getType().equals(dbStatus)){
            throw new DefaultException("仅待执行和暂停的任务可以执行此操作");
        }
        // 暂停任务：仅进行中的任务可以执行此操作
        if(param.getStatus().equals(TaskStatusEnum.PAUSE.getType()) && !TaskStatusEnum.RUNNING.getType().equals(dbStatus)){
            throw new DefaultException("仅进行中的任务可以执行此操作");
        }

        // 取消任务：仅待执行、进行中、暂停的任务可以执行此操作
        if(param.getStatus().equals(TaskStatusEnum.CANCEL.getType()) && !TaskStatusEnum.READY.getType().equals(dbStatus)
                && !TaskStatusEnum.RUNNING.getType().equals(dbStatus) && !TaskStatusEnum.PAUSE.getType().equals(dbStatus)){
            throw new DefaultException("仅待执行、进行中、暂停的任务可以执行此操作");
        }

        // 完成任务：仅进行中和暂停的任务可以执行此操作
        if(param.getStatus().equals(TaskStatusEnum.FINISH.getType()) && !TaskStatusEnum.RUNNING.getType().equals(dbStatus)
                && !TaskStatusEnum.PAUSE.getType().equals(dbStatus)){
            throw new DefaultException("仅进行中和暂停的任务可以执行此操作");
        }

        logTaskMapper.updateStatus(dbData.getId(), param.getBelong(), param.getStatus(), param.getRemark(), new Date());

        // 保存进程日志
        LogTaskProcessAddParamDTO processAddParamDTO = new LogTaskProcessAddParamDTO();
        processAddParamDTO.setBelong(param.getBelong());
        processAddParamDTO.setBusinessId(dbData.getBusinessId());
        processAddParamDTO.setBusinessType(dbData.getBusinessType());
        processAddParamDTO.setTaskId(dbData.getTaskId());
        String content = "任务状态变更为：" + TaskStatusEnum.getNameByType(param.getStatus()) + "，备注：" + ((param.getRemark() == null || "".equals(param.getRemark())) ? "无" : param.getRemark());
        processAddParamDTO.setContent(content);
        logTaskProcessService.add(processAddParamDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteReady(LogTaskDeleteReadyParamDTO param) {

        param.check();

        // 查询参数优先级逻辑
        LogTaskDetailParamDTO queryDTO = new LogTaskDetailParamDTO();
        if(param.getId() != null){
            queryDTO.setId(param.getId());
        } else if(param.getTaskId() != null && !"".equals(param.getTaskId())) {
            queryDTO.setTaskId(param.getTaskId());
        } else {
            queryDTO.setBusinessId(param.getBusinessId());
            queryDTO.setBusinessType(param.getBusinessType());
        }

        // 执行查询
        LogTask dbData = logTaskMapper.getDetail(queryDTO);
        if(dbData == null){
            throw new DefaultException("操作的记录不存在");
        }
        if(!dbData.getStatus().equals(TaskStatusEnum.READY.getType())){
            throw new DefaultException("仅待执行的任务允许删除");
        }

        logTaskMapper.deleteById(dbData.getId(), param.getBelong());

        // 保存进程日志
        LogTaskProcessAddParamDTO processAddParamDTO = new LogTaskProcessAddParamDTO();
        processAddParamDTO.setBelong(param.getBelong());
        processAddParamDTO.setBusinessId(dbData.getBusinessId());
        processAddParamDTO.setBusinessType(dbData.getBusinessType());
        processAddParamDTO.setTaskId(dbData.getTaskId());
        processAddParamDTO.setContent("任务被删除");
        logTaskProcessService.add(processAddParamDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    public LogTaskPageResp add(LogTaskAddParamDTO param) {
        param.check();

        // 存在未完成或者未取消的任务，不能再添加
        LogTaskDetailParamDTO existsDTO = new LogTaskDetailParamDTO();
        existsDTO.setBelong(param.getBelong());
        existsDTO.setBusinessId(param.getBusinessId());
        existsDTO.setBusinessType(param.getBusinessType());
        LogTaskDetailResp existsData = getDetail(existsDTO);
        if(existsData != null && !TaskStatusEnum.FINISH.getType().equals(existsData.getStatus()) && !TaskStatusEnum.CANCEL.getType().equals(existsData.getStatus())){
            throw new DefaultException("存在执行中的任务");
        }

        String taskId = UUID.randomUUID().toString().replace("-", "");
        param.setTaskId(taskId);
        param.setDel(0);
        if(param.getCreateTime() == null){
            param.setCreateTime(new Date());
        }
        param.setStatus(TaskStatusEnum.READY.getType());
        param.setPercent(0D);
        logTaskMapper.add(param);

        // 保存进程日志
        LogTaskProcessAddParamDTO processAddParamDTO = new LogTaskProcessAddParamDTO();
        processAddParamDTO.setBelong(param.getBelong());
        processAddParamDTO.setBusinessId(param.getBusinessId());
        processAddParamDTO.setBusinessType(param.getBusinessType());
        processAddParamDTO.setTaskId(taskId);
        processAddParamDTO.setContent("新建任务");
        logTaskProcessService.add(processAddParamDTO);

        LogTaskPageResp item = new LogTaskPageResp();
        item.setId(param.getId());
        item.setBelong(param.getBelong());
        item.setBusinessType(param.getBusinessType());
        item.setBusinessId(param.getBusinessId());
        item.setTaskId(param.getTaskId());
        item.setTaskName(param.getTaskName());
        item.setPercent(param.getPercent());
        item.setStatus(param.getStatus());
        item.setExpectedEndTime(param.getExpectedEndTime());
        item.setRemark(param.getRemark());
        item.setCreateUserId(param.getCreateUserId());
        item.setCreateUserName(param.getCreateUserName());
        item.setCreateTime(param.getCreateTime());
        item.setUpdateTime(param.getUpdateTime());
        item.setStatusName(statusNameHandler(param.getStatus(), param.getExpectedEndTime()));
        return item;
    }
}
